﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using InterpriseSuiteEcommerceCommon;
using InterpriseSuiteEcommerceCommon.InterpriseIntegration;
using InterpriseSuiteEcommerceCommon.DTO;
using InterpriseSuiteEcommerceGateways;
using System.Text;

namespace InterpriseSuiteEcommerce
{
    public partial class OnePageCheckOut : SkinBase
    {

        private InterpriseShoppingCart _cart = null;
        private bool _cartHasCouponAndIncludesFreeShipping = false;
        private bool isUsingInterpriseGatewayv2 = false;
        private IEnumerable<PaymentTermDTO> paymentTermOptions = null;

        protected void Page_Init(object sender, EventArgs e)
        {

            base.OnLoad(e);
            this._init();

        }

        private void _init()
        {

            isUsingInterpriseGatewayv2 = AppLogic.IsUsingInterpriseGatewayv2();
            OnePageCheckoutHelpfulTips.SetContext = this;

            if (ThisCustomer.IsNotRegistered && !AppLogic.AppConfigBool("PasswordIsOptionalDuringCheckout"))
            {
                Response.Redirect("createaccount1.aspx?checkout=true");
            }

            var script = new StringBuilder();

            script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { \n");

            script.AppendFormat("   ise.Pages.CheckOutPayment.setPaymentTermControlId('{0}');\n", this.ctrlPaymentTerm.ClientID);
            script.AppendFormat("   ise.Pages.CheckOutPayment.setForm('{0}');\n", this.OnePageCheckout.ClientID);

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");

            SectionTitle = AppLogic.GetString("checkoutpayment.aspx.9", SkinID, ThisCustomer.LocaleSetting);
            Page.ClientScript.RegisterStartupScript(this.GetType(), Guid.NewGuid().ToString(), script.ToString());

            SetCacheability();

            RequireSecurePage();
            RequireCustomerRecord();

            InitializeShoppingCart();
            InitializeShippingMethodControl();
            InitializePaymentTermControl();

            if (IsCreditCardTokenizationEnabled)
            {
                StringBuilder _html = new StringBuilder();

                CreditCardOptionsRenderer();

                _html.Append("<div id='save-card-as-text-place-holder' class='float-left'>*Save card as:</div>");
                _html.Append("<div id='save-card-as-input-place-holder' class='float-left'><input type='text' class='light-style-input' id='card-description'/></div>");
                _html.Append("<div class='clr5'></div>");
                _html.Append("<div id='save-this-credit-info-checkbox-place-holder' class='float-left'><input id='save-this-credit-info-checkbox' class='light-style-input' type='checkbox'/></div>");
                _html.Append("<div id='save-this-credit-info-text-place-holder' class='float-left'>Save this credit card information</div>");
                _html.Append("<div class='clear-both height-5'></div>");

                SaveCardAsLtr.Text = _html.ToString();

                _html.Clear();

            }
            else { SaveCardAsLtr.Text = string.Empty; }

            if (_cart.CartItems.Count > 0)
            {
                CheckIfWeShouldRequirePayment();
            }

            DisplayErrorMessageIfAny();
            OrderSummaryFooterRenderer();
        }

        private void SetCacheability()
        {
            Response.CacheControl = "private";
            Response.Expires = 0;
            Response.AddHeader("pragma", "no-cache");
        }

        protected override void RegisterScriptsAndServices(ScriptManager manager)
        {
            manager.Scripts.Add(new ScriptReference("~/jscripts/shippingmethod_ajax.js"));
            manager.Services.Add(new ServiceReference("~/actionservice.asmx"));

            manager.Scripts.Add(new ScriptReference("~/jscripts/tooltip.js"));
            manager.Scripts.Add(new ScriptReference("~/jscripts/creditcard.js"));
            manager.Scripts.Add(new ScriptReference("~/jscripts/paymentterm_ajax.js"));
            manager.Scripts.Add(new ScriptReference("~/jscripts/checkoutpayment_ajax.js"));
        }

        private void InitializeShoppingCart()
        {
            _cart = new InterpriseShoppingCart(base.EntityHelpers, ThisCustomer.SkinID, ThisCustomer, CartTypeEnum.ShoppingCart, string.Empty, false, true);
            bool computeVat = AppLogic.AppConfigBool("Vat.Enabled");
            if (_cart.CartItems.Count > 0)
            {
                _cart.BuildSalesOrderDetails();
                _cartHasCouponAndIncludesFreeShipping = _cart.CouponIncludesFreeShipping();
            }
            else{ Response.Redirect("shoppingcart.aspx"); }

            if (_cart.HasRegistryItems()) Response.Redirect("checkoutshippingmult.aspx");
        }

        private void InitializeShippingMethodControl()
        {
            ctrlShippingMethod.ShowRefreshLink = false;
            InitializeShippingMethodControlValues();

            AssignShippingMethodValidationPrerequisites();
            InitializeShippingMethodCaptions();
        }

        private void InitializeShippingMethodControlValues()
        {
            if (_cartHasCouponAndIncludesFreeShipping)
            {
                ctrlShippingMethod.Visible = false;
            }
            else
            {
                Address shippingAddress = null;

                if (_cart.OnlyShippingAddressIsNotCustomerDefault())
                {
                    shippingAddress = Address.Get(ThisCustomer, AddressTypes.Shipping, _cart.FirstItem().m_ShippingAddressID);
                }
                else
                {
                    shippingAddress = ThisCustomer.PrimaryShippingAddress;
                }

                ctrlShippingMethod.ShippingAddress = shippingAddress;
            }
        }

        private void AssignShippingMethodValidationPrerequisites()
        {
            ctrlShippingMethod.ShippingMethodRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.9", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }

        private void InitializeShippingMethodCaptions()
        {
            ctrlShippingMethod.RefreshCommandCaption = AppLogic.GetString("checkout1.aspx.7", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);

            if (!_cart.CartAllowsShippingMethodSelection) return;

            if (_cartHasCouponAndIncludesFreeShipping)
            {
                lblSelectShippingMethod.Text = AppLogic.GetString("checkoutshipping.aspx.5", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            }
            else
            {
                if (ThisCustomer.IsRegistered && Shipping.MultiShipEnabled() && _cart.TotalQuantity() > 1)
                {
                    lblSelectShippingMethod.Text = string.Format(AppLogic.GetString("checkoutshipping.aspx.7", SkinID, ThisCustomer.LocaleSetting), "checkoutshippingmult.aspx");
                }
                else
                {
                    lblSelectShippingMethod.Text = AppLogic.GetString("checkout1.aspx.4", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
                }
            }
        }

        private void InitializePaymentTermControl()
        {
            string baseTermOnThisCustomer = CommonLogic.IIF(ThisCustomer.IsNotRegistered, ThisCustomer.AnonymousCustomerCode, ThisCustomer.CustomerCode);
            paymentTermOptions = PaymentTermDTO.GetAllForGroup(baseTermOnThisCustomer, ThisCustomer.PrimaryShippingAddress); //availableTerms;

            ctrlPaymentTerm.PaymentTermOptions = paymentTermOptions; ;
            ctrlPaymentTerm.CaptionWidth = Unit.Percentage(30);
            ctrlPaymentTerm.InputWidth = Unit.Percentage(70);
            ctrlPaymentTerm.ShowCardStarDate = AppLogic.AppConfigBool("ShowCardStartDateFields");

            AssignPaymentTermDatasources();
            InitializePaymentTermControlValues();
            AssignPaymentTermCaptions();
            AssignPaymentTermErrorSummary();
            AssignPaymentTermValidationPrerequisites();
            InitializeTermsAndConditions();
        }

        private void AssignPaymentTermDatasources()
        {
            int currentYear = DateTime.Now.Year;
            var startYears = new List<string>();
            var expirationYears = new List<string>();
            DataView cardTypeViewDataSource = AppLogic.GetCustomerCreditCardType(AppLogic.GetString("address.cs.5", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));

            startYears.Add(AppLogic.GetString("address.cs.8", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
            expirationYears.Add(AppLogic.GetString("address.cs.8", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));

            for (int offsetYear = 0; offsetYear <= 10; offsetYear++)
            {
                startYears.Add((currentYear - offsetYear).ToString());
                expirationYears.Add((currentYear + offsetYear).ToString());
            }

            var months = new List<string>();
            months.Add(AppLogic.GetString("address.cs.7", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
            for (int month = 1; month <= 12; month++)
            {
                months.Add(month.ToString().PadLeft(2, '0'));
            }

            ctrlPaymentTerm.CardTypeViewDataSource = cardTypeViewDataSource;
            ctrlPaymentTerm.StartYearDataSource = startYears;
            ctrlPaymentTerm.ExpiryYearDataSource = expirationYears;
            ctrlPaymentTerm.StartMonthDataSource = months;
            ctrlPaymentTerm.ExpiryMonthDataSource = months;
        }

        private void InitializePaymentTermControlValues()
        {
            if (!ThisCustomer.IsRegistered) return;

            ctrlPaymentTerm.NameOnCard = ThisCustomer.PrimaryBillingAddress.CardName;
            ctrlPaymentTerm.CardExpiryMonth = ThisCustomer.PrimaryBillingAddress.CardExpirationMonth;
            ctrlPaymentTerm.CardExpiryYear = ThisCustomer.PrimaryBillingAddress.CardExpirationYear;
            ctrlPaymentTerm.CardType = ThisCustomer.PrimaryBillingAddress.CardType;
            ctrlPaymentTerm.CardStartMonth = ThisCustomer.PrimaryBillingAddress.CardStartMonth;
            ctrlPaymentTerm.CardStartYear = ThisCustomer.PrimaryBillingAddress.CardStartYear;
        }

        private void AssignPaymentTermCaptions()
        {
            ctrlPaymentTerm.NameOnCardCaption = AppLogic.GetString("address.cs.1", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardNumberCaption = AppLogic.GetString("address.cs.2", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardTypeCaption = AppLogic.GetString("address.cs.4", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CVVCaption = AppLogic.GetString("address.cs.3", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardStartDateCaption = AppLogic.GetString("checkout1.aspx.22", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardIssueNumberCaption = AppLogic.GetString("checkout1.aspx.23", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardIssueNumberInfoCaption = AppLogic.GetString("checkout1.aspx.24", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.WhatIsCVVCaption = AppLogic.GetString("address.cs.9", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.ExpirationDateCaption = AppLogic.GetString("address.cs.6", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.PONumberCaption = AppLogic.GetString("checkoutpo.aspx.1", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.NoPaymentRequiredCaption = AppLogic.GetString("checkoutpayment.aspx.8", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.ExternalCaption = AppLogic.GetString("gw.paypal.display", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);

        }

        private void AssignPaymentTermErrorSummary()
        {
            ctrlPaymentTerm.ErrorSummaryControl = this.errorSummary;
        }

        private void AssignPaymentTermValidationPrerequisites()
        {
            ctrlPaymentTerm.PaymentTermRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.10", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.NameOnCardRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.11", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardNumberRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.12", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CVVRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.13", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardTypeInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.14", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.ExpirationMonthInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.15", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.StartMonthInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.25", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.StartYearInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.26", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.ExpirationYearInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.16", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.UnknownCardTypeErrorMessage = AppLogic.GetString("checkout1.aspx.17", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.NoCardNumberProvidedErrorMessage = AppLogic.GetString("checkout1.aspx.18", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardNumberInvalidFormatErrorMessage = AppLogic.GetString("checkout1.aspx.19", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardNumberInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.20", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.CardNumberInAppropriateNumberOfDigitsErrorMessage = AppLogic.GetString("checkout1.aspx.21", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            ctrlPaymentTerm.StoredCardNumberInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.27", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }

        private void InitializeTermsAndConditions()
        {
            if (AppLogic.AppConfigBool("RequireTermsAndConditionsAtCheckout"))
            {
                Topic t = new Topic("checkouttermsandconditions", ThisCustomer.LocaleSetting, ThisCustomer.SkinID);
                string resouce1 = AppLogic.GetString("checkoutpayment.aspx.5", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);

                ctrlPaymentTerm.RequireTermsAndConditions = true;
                ctrlPaymentTerm.RequireTermsAndConditionsPrompt = resouce1;
                ctrlPaymentTerm.TermsAndConditionsHTML = t.Contents;
            }
            else
            {
                ctrlPaymentTerm.RequireTermsAndConditions = false;
            }
        }

        private void CheckIfWeShouldRequirePayment()
        {

            if (_cart.GetOrderBalance() == System.Decimal.Zero && AppLogic.AppConfigBool("SkipPaymentEntryOnZeroDollarCheckout"))
            {
                ctrlPaymentTerm.NoPaymentRequired = true;
                _cart.MakePaymentTermNotRequired();
            }
            else
            {
                ctrlPaymentTerm.NoPaymentRequired = false;
            }

        }

        private void CreditCardOptionsRenderer()
        {

            if (ThisCustomer.IsRegistered)
            {

                if (!this.IsPostBack)
                {
                    AppLogic.GenerateCreditCardCodeSaltIV(ThisCustomer);
                }

                var creditCards = CreditCardDTO.GetCreditCards(ThisCustomer.CustomerCode);

                StringBuilder _CreditOptionsHTML = new StringBuilder();
                string _default = "---";

                _CreditOptionsHTML.Append("<span class='strong-font'>Saved Credit Card Info</span>");
                _CreditOptionsHTML.Append("<div class='clear-both height-12'></div>");


                _CreditOptionsHTML.Append("<div id='credit-card-options-wrapper'>");

                _CreditOptionsHTML.Append("<div id='credit-card-options-header-wrapper'>");

                _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-code-place-holder float-left custom-font-style'>{0}</div>", string.Empty);
                _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-name-place-holder float-left custom-font-style'>{0}</div>", "Card Name");
                _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-type-place-holder float-left custom-font-style'>{0}</div>", "Card Type");
                _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-expiry-place-holder float-left custom-font-style'>{0}</div>", "Expiry");
                _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-clear-link-place-holder float-left custom-font-style'>{0}</div>", string.Empty);

                _CreditOptionsHTML.Append("</div>");

                _CreditOptionsHTML.Append("<div class='clear-both'></div>");

                int counter = 1;
                string thisOption = string.Empty;

                foreach (CreditCardDTO credit in creditCards)
                {

                    if (counter == 1)
                    {

                        thisOption = "checked";

                    }
                    else
                    {

                        thisOption = string.Empty;

                    }

                    string creditCardCode = AppLogic.EncryptCreditCardCode(ThisCustomer, credit.CreditCardCode);
                    string creditOption = string.Format("<input type='radio' id='{2}' {1} name='credit-card-code' value = '{0}'/>", creditCardCode, thisOption, counter);

                    string description = string.Empty;

                    if (credit.RefNo > 0)
                    {
                        description = credit.Description;
                    }

                    _CreditOptionsHTML.Append("<div class='opc-credit-card-options-row'>");

                    _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-code-place-holder float-left'>{0}</div>", creditOption);
                    _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-name-place-holder float-left'>{0}{1}</div>", credit.NameOnCard, string.Format("<div class='clr5'></div><div id='{1}-credit-card-description'>{0}</div>", description, counter));

                    if (credit.RefNo > 0)
                    {


                        string lastFour = string.Empty;

                        if (credit.CardNumber.Length > 0)
                        {
                            lastFour = credit.CardNumber.Substring(credit.CardNumber.Length - 4);
                            lastFour = string.Format("&nbsp;<span class=\"MaskNumber\">ending in {0}</span>", lastFour);
                        }


                        _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-type-place-holder float-left' id='{2}-credit-card-type'>{0} {1}</div>", credit.CardType, lastFour, counter);
                        _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-expiry-place-holder float-left'  id='{1}-credit-card-expiry'>{0}</div>", string.Format("{0}/{1}", credit.ExpMonth, credit.ExpYear), counter);
                        _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-clear-link-place-holder float-left' id='{1}-credit-card-clear'>{0}</div>", string.Format("<a class='opc-clearcard' id='opc::{0}::{1}' href='javascript:void(1);'>Clear</a>", creditCardCode, counter), counter);

                    }
                    else
                    {

                        _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-type-place-holder float-left'>{0}</div>", _default);
                        _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-expiry-place-holder float-left'>{0}</div>", _default);
                        _CreditOptionsHTML.AppendFormat("<div class='opc-options-credit-card-clear-link-place-holder float-left'>{0}</div>", _default);
                    }


                    _CreditOptionsHTML.Append("</div>");

                    _CreditOptionsHTML.Append("<div class='clear-both'></div>");

                    counter++;

                }

                _CreditOptionsHTML.Append("</div>");
                _CreditOptionsHTML.Append("<div class='clear-both height-12'></div>");

                LtrCreditCardOptionsRenderer.Text = _CreditOptionsHTML.ToString();

            }
        }

        protected bool IsCreditCardTokenizationEnabled
        {
            get { return isUsingInterpriseGatewayv2 && ThisCustomer.IsRegistered && AppLogic.AppConfigBool("AllowCreditCardInfoSaving"); }
        }

        private void DisplayErrorMessageIfAny()
        {
            string errorMessage = CommonLogic.QueryStringCanBeDangerousContent("ErrorMsg", true);
            DisplayErrorMessageIfAny(errorMessage);
        }

        private void DisplayErrorMessageIfAny(string errorMessage)
        {
            if (CommonLogic.IsStringNullOrEmpty(errorMessage)) return;

            if (errorMessage.IndexOf("<script>", StringComparison.InvariantCultureIgnoreCase) != -1)
            {
                throw new ArgumentException("SECURITY EXCEPTION");
            }

            if (errorMessage == AppLogic.ro_INTERPRISE_GATEWAY_AUTHORIZATION_FAILED)
            {
                if (AppLogic.AppConfigBool("ShowGatewayError"))
                {
                    errorMessage = ThisCustomer.ThisCustomerSession["LastGatewayErrorMessage"];
                }
                else
                {
                    errorMessage = AppLogic.GetString("checkoutpayment.aspx.cs.1", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
                }
            }

            errorSummary.DisplayErrorMessage(errorMessage);
        }

        protected void btnDoProcessPayment_Click(object sender, EventArgs e)
        {
            try
            {
                ProcessPayment();
            }
            catch (Exception ex)
            {
                errorSummary.DisplayErrorMessage(ex.Message);
            }
        }

        protected override void OnUnload(EventArgs e)
        {
            if (_cart != null)
            {
                _cart.Dispose();
            }

            base.OnUnload(e);
        }

        protected void ProcessPayment()
        {
            #region Instatiate Customer and Shopping Cart (BuildSalesOrderDetails)

            Customer thisCustomer = Customer.Current;
            thisCustomer.RequireCustomerRecord();

            if (_cart.CartItems.Count > 0) _cart.BuildSalesOrderDetails();
 
            #endregion

            #region Update Anonymous Customer

            if (ThisCustomer.IsNotRegistered)
            {
                int isupdated = 1;
                string updateAnonRecordIfIsover13checked = string.Format("UPDATE EcommerceCustomer SET IsOver13 = 1, IsUpdated = {0} WHERE CustomerID = {1}", DB.SQuote(isupdated.ToString()), DB.SQuote(ThisCustomer.CustomerID.ToString()));
                DB.ExecuteSQL(updateAnonRecordIfIsover13checked);

                ThisCustomer.Update();
            }

            #endregion

            #region Static Data

            string cardNumberInvalidErrorMessage = string.Empty;

            string PaymentTermRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.10", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string NameOnCardRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.11", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string CardNumberRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.12", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string CVVRequiredErrorMessage = AppLogic.GetString("checkout1.aspx.13", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string CardTypeInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.14", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string ExpirationMonthInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.15", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string StartMonthInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.25", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string StartYearInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.26", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string ExpirationYearInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.16", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string UnknownCardTypeErrorMessage = AppLogic.GetString("checkout1.aspx.17", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string NoCardNumberProvidedErrorMessage = AppLogic.GetString("checkout1.aspx.18", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string CardNumberInvalidFormatErrorMessage = AppLogic.GetString("checkout1.aspx.19", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string CardNumberInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.20", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string CardNumberInAppropriateNumberOfDigitsErrorMessage = AppLogic.GetString("checkout1.aspx.21", thisCustomer.SkinID, thisCustomer.LocaleSetting);
            string StoredCardNumberInvalidErrorMessage = AppLogic.GetString("checkout1.aspx.27", thisCustomer.SkinID, thisCustomer.LocaleSetting);

            string PAYMENT_METHOD_PAYPALX = InterpriseSuiteEcommerceControls.PaymentTermControl.PAYMENT_METHOD_PAYPALX;
            string PAYMENT_METHOD_CREDITCARD = InterpriseSuiteEcommerceControls.PaymentTermControl.PAYMENT_METHOD_CREDITCARD;

            bool saveCreditCardInfo = false;
            bool invalid = false;
            bool skipCreditCardValidation = false;

            #endregion

            #region Posted Data (Credit Card Information)

            string _PONumber = string.Empty;

            string _NameOnCard = ctrlPaymentTerm.NameOnCard;
            string _CardNumber = ctrlPaymentTerm.CardNumber;

            string _CardType = ctrlPaymentTerm.CardType;
            string _CardExpiryYear = ctrlPaymentTerm.CardExpiryYear;
            string _CardExpiryMonth = ctrlPaymentTerm.CardExpiryMonth;
            string _CVV = ctrlPaymentTerm.CVV;

            string _SaveCreditCardAs = txtDescription.Text;
            string _CustomerCreditCardCode = string.Empty;

            string _PaymentTermCode = ctrlPaymentTerm.PaymentTermCode;
            string _PaymentMethod = ctrlPaymentTerm.PaymentMethod;

            string _CardStartMonth = string.Empty;
            string _CardStartYear = string.Empty;
            string _CardIssueNumber = string.Empty;

            if (AppLogic.AppConfigBool("ShowCardStartDateFields"))
            {
                _CardStartMonth  = ctrlPaymentTerm.CardStartMonth;
                _CardStartYear   = ctrlPaymentTerm.CardStartYear;
                _CardIssueNumber = ctrlPaymentTerm.CardIssueNumber;

            }

            #endregion

            #region Save Billing Address

            bool _IsCreditCardTokenizationEnabled = isUsingInterpriseGatewayv2 && Customer.Current.IsRegistered && AppLogic.AppConfigBool("AllowCreditCardInfoSaving");

            Address aBillingAddress = Address.New(ThisCustomer, AddressTypes.Billing);

            Address ThisAddress = Address.New(ThisCustomer, AddressTypes.Shipping);
            Address aShippingAddress = ThisAddress.ThisCustomer.PrimaryShippingAddress;

            if (!copyShippingInfo.Checked)
            {
                aBillingAddress.Address1 = BillingAddressControl.street;
                aBillingAddress.Country = BillingAddressControl.country;
                aBillingAddress.PostalCode = BillingAddressControl.postal;

                string bCityStates = txtCityStates.Text;
                string city = string.Empty;
                string state = string.Empty;

                if (!string.IsNullOrEmpty(bCityStates))
                {
                    var _cityState = bCityStates.Split(',');
                    state = _cityState[0].Trim();
                    city = _cityState[1].Trim();

                }
                else
                {

                    state = BillingAddressControl.state;
                    city = BillingAddressControl.city;
                }

                aBillingAddress.City = city;
                aBillingAddress.State = state;

                aBillingAddress.ResidenceType = aShippingAddress.ThisCustomer.PrimaryShippingAddress.ResidenceType;
                aBillingAddress.Name = txtBillingContactName.Text;
                aBillingAddress.Phone = txtBillingAreaCode.Text + " " + txtBillingPrimaryPhone.Text;

                if (AppLogic.AppConfigBool("Address.ShowCounty")) { aBillingAddress.County = BillingAddressControl.county; }
            }
            else
            {
                aBillingAddress.Address1 = aShippingAddress.Address1;
                aBillingAddress.Country = aShippingAddress.Country;
                aBillingAddress.PostalCode = aShippingAddress.PostalCode;
                aBillingAddress.City = aShippingAddress.City;
                aBillingAddress.State = aShippingAddress.State;
                aBillingAddress.ResidenceType = aShippingAddress.ResidenceType;
                aBillingAddress.Name = aShippingAddress.Name;
                aBillingAddress.Phone = aShippingAddress.Phone;

                if (AppLogic.AppConfigBool("Address.ShowCounty")) { aBillingAddress.County = aShippingAddress.County; }
            }

            string maskedCardNumber = string.Empty;
            string creditCardCode = string.Empty;

            if (_IsCreditCardTokenizationEnabled && txtCode.Text != string.Empty)
            {
                _CustomerCreditCardCode = txtCode.Text;

                creditCardCode = AppLogic.DecryptCreditCardCode(thisCustomer, _CustomerCreditCardCode);
                maskedCardNumber = AppLogic.GetCustomerCreditCardMaskedCardNumber(creditCardCode);
            }

            bool refNoIsNotZero = false;

            if (maskedCardNumber.StartsWith("X"))
            {
                CreditCardDTO credit = null;

                if (creditCardCode != string.Empty)
                {
                    credit = CreditCardDTO.Find(creditCardCode);
                    credit.CreditCardCode = creditCardCode;
                }

                if (credit.RefNo > 0)
                {
                    _CardNumber = credit.CardNumber;
                    _NameOnCard = credit.NameOnCard;
                    _CardType = credit.CardType;
                    _CardExpiryMonth = credit.ExpMonth;
                    _CardExpiryYear = credit.ExpYear;


                    if (AppLogic.AppConfigBool("ShowCardStartDateFields"))
                    {

                        _CardStartMonth = credit.StartMonth;
                        _CardStartYear = credit.StartYear;
                    }

                    refNoIsNotZero = true;
                }
            }

            aBillingAddress.CardNumber = _CardNumber;
            aBillingAddress.CardName = _NameOnCard;
            aBillingAddress.CardType = _CardType;
            aBillingAddress.CardExpirationMonth = _CardExpiryMonth;
            aBillingAddress.CardExpirationYear = _CardExpiryYear;

            aBillingAddress.Save();

            aBillingAddress.AddressID = thisCustomer.PrimaryBillingAddressID;
            aBillingAddress.CustomerCode = thisCustomer.CustomerCode;

            Address.Update(thisCustomer, aBillingAddress);

            #endregion

            #region Payments

            if (AppLogic.AppConfigBool("ForceCreditCardInfoSaving")) saveCreditCardInfo = true;  /* <-- AppConfig: ForceCreditCardInfoSaving if true force saving of credit card info */

            if (_cart.GetOrderBalance() == System.Decimal.Zero && AppLogic.AppConfigBool("SkipPaymentEntryOnZeroDollarCheckout"))
            {
                _cart.MakePaymentTermNotRequired();
            }

            if (_PaymentTermCode.ToString().Trim().Equals("PURCHASE ORDER", StringComparison.InvariantCultureIgnoreCase))
            {
                thisCustomer.ThisCustomerSession.SetVal("PONumber", _PONumber);
            }
            else if (_PaymentTermCode.ToString().Trim().Equals("REQUEST QUOTE", StringComparison.InvariantCultureIgnoreCase))
            { }
            else if (_PaymentMethod == PAYMENT_METHOD_PAYPALX)
            {
                thisCustomer.ThisCustomerSession["paypalfrom"] = "onepagecheckout";
                Response.Redirect(PayPalExpress.CheckoutURL(_cart));
            }
            else if (_PaymentMethod == PAYMENT_METHOD_CREDITCARD)
            {

                #region Validate Credit Card

                bool IsCreditCardNoMasked = false;


                //-> See if we should use the card number on file.
                //-> We also want to see if the card number starts with an *.
                //-> If it doesn't it probably means the user entered a new number.

                //-> See if we should use the card number on file.
                //-> We also want to see if the card number starts with an *.
                //-> If it doesn't it probably means the user entered a new number.

                if (maskedCardNumber.StartsWith("X") && refNoIsNotZero)
                {
                    //-> Get the stored card number.

                    _CardNumber = ThisCustomer.PrimaryBillingAddress.CardNumber;
                    cardNumberInvalidErrorMessage = StoredCardNumberInvalidErrorMessage;

                    skipCreditCardValidation = true;
                    IsCreditCardNoMasked = false;
                }
                else
                {
                    //-> Get the card number the user entered.
                    cardNumberInvalidErrorMessage = CardNumberInvalidErrorMessage;

                }

                var ccValidator = new CreditCardValidator();

                //-> Validate Expiration Date
                if (!ccValidator.IsValidExpirationDate(string.Concat(_CardExpiryYear, _CardExpiryMonth)))
                {
                    errorSummary.DisplayErrorMessage(ExpirationMonthInvalidErrorMessage);
                    errorSummary.DisplayErrorMessage(ExpirationYearInvalidErrorMessage);
                    invalid = true;
                }

                ccValidator.AcceptedCardTypes = _CardType;

                if (ccValidator.AcceptedCardTypes.Contains("0"))
                {
                    errorSummary.DisplayErrorMessage(CardTypeInvalidErrorMessage);
                    invalid = true;
                }

               
                if (((!ccValidator.IsValidCardType(_CardNumber) || !ccValidator.ValidateCardNumber(_CardNumber)) && (!skipCreditCardValidation)))
                {
                    errorSummary.DisplayErrorMessage(cardNumberInvalidErrorMessage);
                    invalid = true;
                }

                #endregion

                if (!invalid)
                {
                    if (AppLogic.AppConfigBool("ShowCardStartDateFields"))
                    {
                        //-> Some CCs do not have StartDate, so here we should provide Default if none was supplied.

                        string defaultCardStartMonth = DateTime.Now.Month.ToString();
                        string defaultCardStartYear = DateTime.Now.Year.ToString();

                        aBillingAddress.CardStartMonth = CommonLogic.IIF(_CardStartMonth != "MONTH", _CardStartMonth, defaultCardStartMonth);
                        aBillingAddress.CardStartYear = CommonLogic.IIF(_CardStartYear != "YEAR", _CardStartYear, defaultCardStartYear);

                        aBillingAddress.CardIssueNumber = _CardIssueNumber;

                    }

                    //-> Capture the credit card number from the payment page and encrypt it so that the gateway can capture from that credit card

                    if (!IsCreditCardNoMasked)
                    {

                        string salt = null;
                        string iv = null;
                        string cardNumberEnc = AppLogic.EncryptCardNumber(_CardNumber, ref salt, ref iv);

                        AppLogic.StoreCardNumberInSession(thisCustomer, cardNumberEnc, salt, iv);

                    }

                    ThisCustomer.ThisCustomerSession["SaveCreditCardChecked"] = "false";

                    if (_IsCreditCardTokenizationEnabled)
                    {
                        _CustomerCreditCardCode = txtCode.Text;
                        creditCardCode = AppLogic.DecryptCreditCardCode(thisCustomer, _CustomerCreditCardCode);

                        InterpriseHelper.MakeDefaultAddress(thisCustomer.ContactCode, creditCardCode, AddressTypes.Billing);

                        thisCustomer.PrimaryBillingAddressID = creditCardCode;
                        thisCustomer.PrimaryBillingAddress.AddressID = creditCardCode;

                        thisCustomer.ThisCustomerSession["SaveCreditCardChecked"] = saveCreditCardInfo.ToString();

                        #region "Update Address w/ CreditCardInfo"

                        string thisCardNumber = Interprise.Framework.Base.Shared.Common.MaskCardNumber(aBillingAddress.CardNumber);

                        if (!string.IsNullOrEmpty(maskedCardNumber))
                        {
                            thisCardNumber = maskedCardNumber;
                        }

                        DB.ExecuteSQL(@"UPDATE CustomerCreditCard
                                            SET CreditCardDescription={1},
	                                            MaskedCardNumber={2},
	                                            NameOnCard={3},
	                                            Address={4},
	                                            City={5},
	                                            State={6},
	                                            PostalCode={7},
	                                            Country={8},
	                                            ExpMonth={9},
	                                            ExpYear={10},
	                                            Telephone={11},
	                                            CreditCardType={12},
                                                DateModified=getdate()
	                                            WHERE CreditCardCode={0}",
                                        DB.SQuote(creditCardCode),
                                        DB.SQuote(_SaveCreditCardAs),
                                        DB.SQuote(thisCardNumber),
                                        DB.SQuote(_NameOnCard),
                                        DB.SQuote(aBillingAddress.Address1),
                                        DB.SQuote(aBillingAddress.City),
                                        DB.SQuote(aBillingAddress.State),
                                        DB.SQuote(aBillingAddress.PostalCode),
                                        DB.SQuote(aBillingAddress.Country),
                                        DB.SQuote(InterpriseHelper.ToInterpriseExpMonth(aBillingAddress.CardExpirationMonth)),
                                        DB.SQuote(aBillingAddress.CardExpirationYear),
                                        DB.SQuote(aBillingAddress.Phone),
                                        DB.SQuote(aBillingAddress.CardType));

                        #endregion

                        thisCustomer.ThisCustomerSession["SaveCreditCardChecked"] = "true";

                        DB.ExecuteSQL(@"UPDATE Customer SET Creditcardcode={0} WHERE CustomerCode={1}", DB.SQuote(creditCardCode), DB.SQuote(thisCustomer.CustomerCode));

                        AppLogic.ClearCreditCardCodeInSession(ThisCustomer);

                        aBillingAddress.AddressID = thisCustomer.PrimaryBillingAddressID;
                        aBillingAddress.CustomerCode = thisCustomer.CustomerCode;

                        Address.Update(thisCustomer, aBillingAddress);
                    }
                    
                    AppLogic.StoreCardExtraCodeInSession(thisCustomer, _CVV);

                    aShippingAddress.AddressID = thisCustomer.PrimaryShippingAddressID;
                    aShippingAddress.CustomerCode = thisCustomer.CustomerCode;

                    Address.Update(thisCustomer, aShippingAddress);
                }
            }

            #endregion

            #region Redirect to Confirmation Page or Do Place Order

            if (!invalid)
            {

                InterpriseHelper.UpdateCustomerPaymentTerm(thisCustomer, _PaymentTermCode);
                if (AppLogic.AppConfigBool("Checkout.UseOnePageCheckout.UseFinalReviewOrderPage")) Response.Redirect("checkoutreview.aspx");

                string salesOrderCode = string.Empty;
                string receiptCode = string.Empty;
                Gateway gatewayToUse = null;

                string status = _cart.PlaceOrder(gatewayToUse, aBillingAddress, aShippingAddress, ref salesOrderCode, ref receiptCode, true, true, false);

                if (status == AppLogic.ro_3DSecure)
                {
                    // If credit card is enrolled in a 3D Secure service (Verified by Visa, etc.)
                    Response.Redirect("secureform.aspx");

                }
                if (status == AppLogic.ro_OK)
                {
                    thisCustomer.ClearTransactions(true);
                    Response.Redirect(string.Format("orderconfirmation.aspx?ordernumber={0}", Server.UrlEncode(salesOrderCode)));
                }
                else
                {
                    thisCustomer.IncrementFailedTransactionCount();
                    if (thisCustomer.FailedTransactionCount >= AppLogic.AppConfigUSInt("MaxFailedTransactionCount"))
                    {

                        _cart.ClearTransaction();
                        thisCustomer.ResetFailedTransactionCount();

                        Response.Redirect("orderfailed.aspx");

                    }

                    thisCustomer.ClearTransactions(false);
                    errorSummary.DisplayErrorMessage(status);

                }
            }
          
            #endregion
        }

        private void OrderSummaryFooterRenderer()
        {
            StringBuilder output = new StringBuilder();

            RenderOrderSummaryFooter(_cart, ref output);
            litOrderSummaryFooter.Text = output.ToString();
        }


        private void RenderOrderSummaryFooter(InterpriseShoppingCart cart, ref StringBuilder output)
        {
            if (cart.IsEmpty()) return;

            string currencyCode = cart.ThisCustomer.CurrencyCode;
            string localSettings = cart.ThisCustomer.LocaleSetting;

            //// Captions
            string subTotalCaption = AppLogic.GetString("shoppingcart.cs.27", cart.SkinID, cart.ThisCustomer.LocaleSetting);
            string totalCaption = AppLogic.GetString("shoppingcart.cs.11", cart.SkinID, cart.ThisCustomer.LocaleSetting);
            string plusShippingCaption = AppLogic.GetString("shoppingcart.aspx.10", cart.SkinID, localSettings);

            // The values
            decimal subTotal = cart.SalesOrderDataset.CustomerSalesOrderView[0].SubTotalRate;
            decimal tax = cart.SalesOrderDataset.CustomerSalesOrderView[0].TaxRate;
            decimal freight = cart.SalesOrderDataset.CustomerSalesOrderView[0].FreightRate;
            decimal freightTax = cart.SalesOrderDataset.CustomerSalesOrderView[0].FreightTaxRate;

            decimal total = subTotal + tax + freight;
            string totalTaxCaption = string.Empty;

            if (cart.ThisCustomer.VATSettingReconciled == VatDefaultSetting.Inclusive)
            {
                subTotal = subTotal + tax;

                subTotal -= freightTax;
                freight += freightTax;

                totalTaxCaption = AppLogic.GetString("showproduct.aspx.38", cart.ThisCustomer.SkinID, localSettings);
            }
            else
            {
                tax -= freightTax;
                totalTaxCaption = AppLogic.GetString("showproduct.aspx.37", cart.ThisCustomer.SkinID, localSettings);
            }

            //clear the inc/exclude vat if vat is disabled.
            if (!AppLogic.AppConfigBool("VAT.Enabled")) { totalTaxCaption = string.Empty; }

            output.Append("<table class='cart-total-summary' >");

            output.Append("<tr>");
            output.AppendFormat("<td align='left'><span class='summary-highligh-text'>{0}</span><span class='summary-highligh-text total-freight-tax-caption'>{1}</span></td>", subTotalCaption, totalTaxCaption);
            output.Append("<td align=\"right\" valign=\"middle\">");
            string subTotalFormatted = InterpriseHelper.FormatCurrencyForCustomer(subTotal, currencyCode);
            output.AppendFormat("<span id='sub-total-place-holder'>{0}</span>", subTotalFormatted);
            output.Append("</td>");
            output.Append("</tr>");

            output.Append("<tr>");
            output.Append("<td align=\"right\" colspan='2' valign=\"middle\"><hr noshade size='1' class='order-summary-footer-hr'/></td>");
            output.Append("</tr>");

            output.Append("<tr>");
            output.AppendFormat("<td align=\"left\"><span class='summary-highligh-text'>{0}</span><span class='summary-highligh-text total-freight-tax-caption'>{1}</span></td>", plusShippingCaption, totalTaxCaption);
            output.Append("<td align=\"right\" valign=\"middle\">");

            if (cart.HasShippableComponents())
            {
                if (cart.CouponIncludesFreeShipping(cart.ThisCustomer.CouponCode))
                {
                    output.AppendFormat("<span>{0}</span>", (AppLogic.GetString("shoppingcart.aspx.13", cart.SkinID, cart.ThisCustomer.LocaleSetting)));
                }
                else if (InterpriseHelper.IsFreeShippingThresholdEnabled(subTotal) &&
                   InterpriseHelper.ShippingMethodCodeBelongsToFreeShippingMethodList(cart.SalesOrderDataset.CustomerSalesOrderView[0].ShippingMethodCode))
                {
                    output.AppendFormat("<span>{0}</span>", AppLogic.GetString("shoppingcart.aspx.13", cart.SkinID, cart.ThisCustomer.LocaleSetting));
                }
                else
                {
                    output.AppendFormat("<span id='shipping-rate-value-place-holder'>{0}</span>", InterpriseHelper.FormatCurrencyForCustomer(freight, currencyCode));
                }
            }
            else
            {
                output.AppendFormat("<span>{0}</span>", AppLogic.GetString("shoppingcart.aspx.13", cart.SkinID, cart.ThisCustomer.LocaleSetting));
            }

            output.Append("</td>");
            output.Append("</tr>");

            if (cart.ThisCustomer.VATSettingReconciled == VatDefaultSetting.Exclusive)
            {
                output.Append("<tr>");
                output.Append("<td align=\"right\" colspan='2' valign=\"middle\"><hr noshade size='1' class='order-summary-footer-hr'/></td>");
                output.Append("</tr>");

                string freightTaxCaption = AppLogic.GetString("shoppingcart.aspx.30", cart.SkinID, localSettings);
                output.Append("<tr>");
                output.AppendFormat("<td align='left'><span class='summary-highligh-text'>{0}</span></td>", freightTaxCaption);
                output.Append("<td align=\"right\" valign=\"middle\">");
                output.AppendFormat("<span id='freight-tax-place-holder'>{0}</span>", InterpriseSuiteEcommerceCommon.InterpriseHelper.FormatCurrencyForCustomer(freightTax, currencyCode));
                output.Append("</td>");
                output.Append("</tr>");

                string taxCaption = AppLogic.GetString("shoppingcart.aspx.11", cart.SkinID, localSettings);
                output.Append("<tr>");
                output.AppendFormat("<td align='left'><span class='summary-highligh-text'>{0}</span></td>", taxCaption);
                output.Append("<td align=\"right\" valign=\"middle\">");
                output.AppendFormat("<span id='tax-place-holder'>{0}</span>", InterpriseSuiteEcommerceCommon.InterpriseHelper.FormatCurrencyForCustomer(tax, currencyCode));
                output.Append("</td>");
                output.Append("</tr>");
            }

            output.Append("<tr>");
            output.Append("<td align=\"right\" colspan='2' valign=\"middle\"><hr noshade size='1' class='order-summary-footer-hr'/></td>");
            output.Append("</tr>");

            output.Append("<tr>");
            output.AppendFormat("<td align=\"left\"><span class='summary-highligh-text'>{0}</span></td>", totalCaption);
            output.Append("<td align=\"right\" valign=\"middle\">");
            output.AppendFormat("<span id='grand-total-place-holder'>{0}</span>", InterpriseSuiteEcommerceCommon.InterpriseHelper.FormatCurrencyForCustomer(total, currencyCode));
            output.Append("</td>");
            output.Append("</tr>");

            output.Append("</table><div class='clr'></div>");
        }

    }

}